package com.kehanpay.sdk.model;


import com.kehanpay.sdk.exception.APIConnectionException;
import com.kehanpay.sdk.exception.APIException;
import com.kehanpay.sdk.exception.AuthenticationException;
import com.kehanpay.sdk.exception.ChannelException;
import com.kehanpay.sdk.exception.InvalidRequestException;
import com.kehanpay.sdk.net.APIResource;

import java.util.Map;

public class Charge extends APIResource {
	
	//由 Kehanpay 生成的支付对象 ID， 27 位字符串。
    String id;
    
	//值为 "charge"。
    String object;
    
    //支付创建时的 Unix 时间戳。
    Long created;
    
    //是否处于  live 模式。
    Boolean livemode;
    
    //是否已付款。
    Boolean paid;
    
    //是否存在退款信息，无论退款是否成功。
    Boolean refunded;
    
    //支付使用的  app 对象的  id ，expandable 可展开，查看 如何获取App ID 。
    Object app;
    
	//支付使用的第三方支付渠道，详情参考 支付渠道属性值 。
    String channel;
    
    //商户订单号，适配每个渠道对此参数的要求，必须在商户系统内唯一。( alipay : 1-64 位，  wx : 2-32 位， bfb : 1-20 位， upacp : 8-40 位， yeepay_wap :1-50 位， jdpay_wap :1-30 位， cnp_u :8-20 位， cnp_f :8-20 位， qpay :1-30 位， cmb_wallet :10 位纯数字字符串。注：除 cmb_wallet 外的其他渠道推荐使用 8-20 位，要求数字或字母，不允许特殊字符)。
    String orderNo;
    
    //发起支付请求客户端的 IP 地址，格式为 IPv4 整型，如 127.0.0.1。
    String clientIp;
    
    //订单总金额（必须大于0），单位为对应币种的最小货币单位，人民币为分。如订单总金额为 1 元， amount 为 100，么么贷商户请查看申请的借贷金额范围。
    Integer amount;
    
    //清算金额，单位为对应币种的最小货币单位，人民币为分。
    Integer amountSettle;
    
    //3 位 ISO 货币代码，人民币为  cny 。
    String currency;
    
    //商品标题，该参数最长为 32 个 Unicode 字符，银联全渠道（ upacp / upacp_wap ）限制在 32 个字节。
    String subject;
    
    //商品描述信息，该参数最长为 128 个 Unicode 字符， yeepay_wap 对于该参数长度限制为 100 个 Unicode 字符。
    String body;
    
    //订单支付完成时的 Unix 时间戳。（银联支付成功时间为接收异步通知的时间）
    Long timePaid;
    
    //订单失效时的 Unix 时间戳。时间范围在订单创建后的 1 分钟到 15 天，默认为 1 天，创建时间以 Kehanpay 服务器时间为准。 微信对该参数的有效值限制为 2 小时内；银联对该参数的有效值限制为 1 小时内。
    Long timeExpire;
    
    //订单清算时间，用 Unix 时间戳表示。（仅针对个人开发者）
    Long timeSettle;
    
    //支付渠道返回的交易流水号。
    String transactionNo;
    
	//退款详情列表，详见 Refunds 退款 。
    ChargeRefundCollection refunds;
    
	//已退款总金额，单位为对应币种的最小货币单位，例如：人民币为分。
    Integer amountRefunded;
    
    //订单的错误码，详见 错误 中的错误码描述。
    String failureCode;
    
    //订单的错误消息的描述。
    String failureMsg;
    
    //详见 元数据 。
    Map<String, String> metadata;
    
    //支付凭证，用于客户端发起支付。
    Map<String, Object> credential;
    
    //特定渠道发起交易时需要的额外参数，以及部分渠道支付成功返回的额外参数，详细参考 支付渠道 extra 参数说明 。
    Map<String, Object> extra;
    
    //订单附加说明，最多 255 个 Unicode 字符。
    String description;
    
    //结算类型，2个 字符【t1 ,t0 ,d0】。
    String settleType;
    
    public String getSettleType() {
		return settleType;
	}

	public void setSettleType(String settleType) {
		this.settleType = settleType;
	}

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Integer getAmount() {
        return amount;
    }

    public void setAmount(Integer amount) {
        this.amount = amount;
    }

    public Long getCreated() {
        return created;
    }

    public void setCreated(Long created) {
        this.created = created;
    }

    public String getCurrency() {
        return currency;
    }

    public void setCurrency(String currency) {
        this.currency = currency;
    }

    public Boolean getLivemode() {
        return livemode;
    }

    public void setLivemode(Boolean livemode) {
        this.livemode = livemode;
    }

    public Boolean getPaid() {
        return paid;
    }

    public void setPaid(Boolean paid) {
        this.paid = paid;
    }

    public Boolean getRefunded() {
        return refunded;
    }

    public void setRefunded(Boolean refunded) {
        this.refunded = refunded;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getFailureMsg() {
        return failureMsg;
    }

    public void setFailureMsg(String failureMsg) {
        this.failureMsg = failureMsg;
    }

    public String getFailureCode() {
        return failureCode;
    }

    public void setFailureCode(String failureCode) {
        this.failureCode = failureCode;
    }

    public Integer getAmountRefunded() {
        return amountRefunded;
    }

    public void setAmountRefunded(Integer amountRefunded) {
        this.amountRefunded = amountRefunded;
    }

    public Integer getAmountSettle() {
        return amountSettle;
    }

    public void setAmountSettle(Integer amountSettle) {
        this.amountSettle = amountSettle;
    }

    public String getTransactionNo() {
        return transactionNo;
    }

    public void setTransactionNo(String transactionNo) {
        this.transactionNo = transactionNo;
    }

    public String getObject() {
        return object;
    }

    public void setObject(String object) {
        this.object = object;
    }

    public ChargeRefundCollection getRefunds() {
        // API versions 2014-05-19 and earlier render charge refunds as an array
        // instead of an object, meaning there is no sublist URL.
        if (refunds.getURL() == null) {
            refunds.setURL(String.format("/v1/charges/refunds/%s", getId()));
        }
        return refunds;
    }

    public Map<String, String> getMetadata() {
        return metadata;
    }

    public void setMetadata(Map<String, String> metadata) {
        this.metadata = metadata;
    }

    public String getChannel() {
        return channel;
    }

    public void setChannel(String channel) {
        this.channel = channel;
    }

    public Object getApp() {
        return app;
    }

    public void setApp(Object app) {
        this.app = app;
    }

    public void setCredential(Map<String, Object> credential) {
        this.credential = credential;
    }

    public Map<String, Object> getCredential() {
        return credential;
    }

    public Map<String, Object> getExtra() {
        return extra;
    }

    public void setExtra(Map<String, Object> extra) {
        this.extra = extra;
    }

    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    public String getClientIp() {
        return clientIp;
    }

    public void setClientIp(String clientIp) {
        this.clientIp = clientIp;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    public Long getTimePaid() {
        return timePaid;
    }

    public void setTimePaid(Long timePaid) {
        this.timePaid = timePaid;
    }

    public Long getTimeExpire() {
        return timeExpire;
    }

    public void setTimeExpire(Long timeExpire) {
        this.timeExpire = timeExpire;
    }

    public Long getTimeSettle() {
        return timeSettle;
    }

    public void setTimeSettle(Long timeSettle) {
        this.timeSettle = timeSettle;
    }


    /**
     * 创建 charge
     *
     * @param params
     * @return
     * @throws AuthenticationException
     * @throws InvalidRequestException
     * @throws APIConnectionException
     * @throws APIException
     * @throws ChannelException
     */
    public static Charge create(Map<String, Object> params)
            throws AuthenticationException, InvalidRequestException,
            APIConnectionException, APIException, ChannelException {
    	
        return request(RequestMethod.POST, classURL(Charge.class), params, Charge.class);
    }

    /**
     * 查询 charge
     *
     * @param id
     * @return
     * @throws AuthenticationException
     * @throws InvalidRequestException
     * @throws APIConnectionException
     * @throws APIException
     * @throws ChannelException
     */
    public static Charge retrieve(String id) throws AuthenticationException,
            InvalidRequestException, APIConnectionException,
            APIException, ChannelException {
        return request(RequestMethod.GET, instanceURL(Charge.class, id), null, Charge.class);
    }

    /**
     * 查询 charge
     *
     * @param id
     * @param params
     * @return
     * @throws AuthenticationException
     * @throws InvalidRequestException
     * @throws APIConnectionException
     * @throws APIException
     * @throws ChannelException
     */
    public static Charge retrieve(String id, Map<String, Object> params) throws AuthenticationException,
            InvalidRequestException, APIConnectionException,
            APIException, ChannelException {
        return request(RequestMethod.GET, instanceURL(Charge.class, id), params, Charge.class);
    }
    
    /**
     * 查询 charge
     *
     * @param appId
     * @param mch_order_no
     * @return
     * @throws AuthenticationException
     * @throws InvalidRequestException
     * @throws APIConnectionException
     * @throws APIException
     * @throws ChannelException
     */
    public static Charge retrieve(String appId,String mch_order_no, Map<String, Object> params) throws AuthenticationException,
    InvalidRequestException, APIConnectionException,
    APIException, ChannelException {
    	return request(RequestMethod.GET, instanceURL(Charge.class, appId,mch_order_no), params, Charge.class);
    }

    /**
     * 查询 charge
     *
     * @param params
     * @return
     * @throws AuthenticationException
     * @throws InvalidRequestException
     * @throws APIConnectionException
     * @throws APIException
     * @throws ChannelException
     */
    public static ChargeCollection all(Map<String, Object> params)
            throws AuthenticationException, InvalidRequestException,
            APIConnectionException, APIException, ChannelException {
        return request(RequestMethod.GET, classURL(Charge.class), params, ChargeCollection.class);
    }

}
